package org.springblade.metadata.app;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.atlas.AtlasServiceException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.typedef.AtlasEntityDef;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.api.ResultCode;
import org.springblade.metadata.dto.EntityDTO;
import org.springblade.metadata.entity.Category;
import org.springblade.metadata.service.ICategoryService;
import org.springblade.metadata.service.TypeSystemService;
import org.springblade.metadata.service.impl.EntityService;
import org.springblade.metadata.service.impl.GossaryService;
import org.springblade.metadata.vo.CategoryVO;
import org.springblade.metadata.vo.CategoryWrapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.raysdata.atlas.common.SystemConstant;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

@NonDS
@RestController
@AllArgsConstructor
@RequestMapping("v2/entity")
@Slf4j
@Api(value = "entity", tags = "entity")
public class EntityController {

	private ICategoryService categoryService;

	private TypeSystemService typeSystemService;

	private EntityService entityService;

	private GossaryService gossaryService;

	@PostMapping("/submit")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "新增或修改", notes = "传入EntityDTO   ")
	public R submit(@Valid @RequestBody EntityDTO dto, BladeUser user) {

		if (dto.getCategoryId() == null) {
			return R.fail(ResultCode.PARAM_MISS, "categoryId");
		}

		Category c = categoryService.getById(dto.getCategoryId());
		if (null == c) {
			return R.fail(ResultCode.PARAM_VALID_ERROR);
		}

		AtlasEntityWithExtInfo e = dto.getEntity();

		String type = e.getEntity().getTypeName();
		if (StringUtils.isBlank(type)) {
			return R.fail(ResultCode.PARAM_MISS, "type");
		}

		AtlasEntityDef def = typeSystemService.getEntityByName(type);

		if (def == null) {
			return R.fail(ResultCode.PARAM_MISS, "type");
		}

		try {

			AtlasEntityWithExtInfo we = dto.getEntity();

			Map<String, String> cas = we.getEntity().getCustomAttributes();
			if(cas == null) {
				cas = new HashMap<>();
			}
			if(StringUtils.isNotEmpty(dto.getGrade())) {
				cas.put(SystemConstant.USER_DEFINED_GRADE, dto.getGrade());
			}
			if(user!=null) {
				cas.put(SystemConstant.USER_DEFINED_USERID, user.getUserId().toString());
				cas.put(SystemConstant.USER_DEFINED_USERNAME, user.getUserName());
				we.getEntity().setCreatedBy(user.getUserName());
			}
			
			we.getEntity().setCustomAttributes(cas);
			AtlasEntity res = entityService.save(we);
			if (res == null) {
				if(StringUtils.isNotEmpty(we.getEntity().getGuid())&&!we.getEntity().getGuid().equals("-1")) {
					log.info("no update {}",we.toString());
				}else {
					return R.fail(ResultCode.FAILURE, we.toString());
				}
				entityService.setLable(we.getEntity().getGuid(), we.getEntity().getLabels());
				return R.data(entityService.get(we.getEntity().getGuid()));
			}else {
				
				String termId = gossaryService.getGuidByCategaryid(c);
				
				gossaryService.assignTermToEntities(termId, res.getGuid());
			}
            

			if(CollectionUtils.isNotEmpty(dto.getLables())) {
				entityService.addLable(res.getGuid(), dto.getLables());
			}

			return R.data(entityService.get(res.getGuid()));

		} catch (AtlasServiceException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return R.fail(ResultCode.FAILURE,e1.getMessage());
		}
	}
	@PostMapping("/delete")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "delete", notes = "传入entity guid   ")
	public R delete(@Valid @RequestParam String guid, BladeUser user) {
		
		try {
			AtlasEntityHeader  eh = entityService.delete(guid);
			
			return R.data(eh);
		} catch (AtlasServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return R.fail(ResultCode.FAILURE,e.getMessage());
		}
		
	}
	@PostMapping("/pure")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "pure", notes = "传入entity guid   ")
	public R pure(@Valid @RequestParam String guid, BladeUser user) {
		
		try {
			 entityService.pure(guid);
			
			return R.success(ResultCode.SUCCESS);
		} catch (AtlasServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return R.fail(ResultCode.FAILURE,e.getMessage());
		}
		
	}
	@PostMapping("/group/delete")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "delete", notes = "传入 category ids   ")
	public R deleteGroup(@Valid @RequestParam String ids, BladeUser user) {
		
		try {
			
			gossaryService.remove(ids);
			
			return R.success(ResultCode.SUCCESS);
		} catch (AtlasServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return R.fail(ResultCode.FAILURE,e.getMessage());
		}
		
	}
	/**
	 * 列表
	 */
	@PostMapping("search/basic")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "列表", notes = "")
	public R list(  @RequestBody SearchParameters searchParameters) {
		AtlasSearchResult result;
		try {
			result = entityService.search(searchParameters);
			return R.data(result);
		} catch (AtlasServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return R.fail(e.getMessage());
		}
	}
	
	
}
